package main

import (
	"fmt"
	"sync"
)

type empty = struct{}

func main() {

	chCat := make(chan empty, 1)
	chDog := make(chan empty, 1)
	chFish := make(chan empty, 1)

	wg := sync.WaitGroup{}
	wg.Add(3)

	go run(chCat, chDog, "cat", &wg)
	go run(chDog, chFish, "dog", &wg)
	go run(chFish, chCat, "fish", &wg)

	chCat <- empty{}
	wg.Wait()

	close(chCat)
	close(chDog)
	close(chFish)

	hi := <-chCat

	fmt.Println("hi", hi)
}

func run(ch chan empty, nextCha chan empty, animal string, wg *sync.WaitGroup) {

	for i := 0; i < 100; i++ {
		// wait channel
		<-ch

		fmt.Println(animal, i)

		nextCha <- empty{}
	}

	wg.Done()
}
